/*
 * Copyright 2012 Finbudget.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package finbudgettable.client.ui.grid.cell.description;

import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.ui.PopupPanel;
import finbudgettable.client.ui.grid.Utils;
import finbudgettable.client.ui.grid.cell.AbstractPopupCell;

public class DescriptionCell extends AbstractPopupCell<String, DescriptionCellEditor> {

    interface Resources extends ClientBundle {

        interface Style extends CssResource {
            @ClassName("b-description-cell__html")
            String bDescriptionCell__html();

            @ClassName("b-description-cell__text")
            String bDescriptionCell__text();

            @ClassName("b-description-cell")
            String bDescriptionCell();
        }

        @Source("DescriptionCell.css")
        Style style();
    }

    interface Template extends SafeHtmlTemplates {
        @Template("<div class=\"{0}\">{1}</div>")
        SafeHtml text(String className, String value);

        @Template("<div class=\"{0}\">{1}</div>")
        SafeHtml html(String className, SafeHtml value);
    }

    public static final int MIN_TEXTAREA_WIDTH = 200;
    private static final Template TEMPLATE = GWT.create(Template.class);
    static final Resources RESOURCES = GWT.create(Resources.class);

    static {
        RESOURCES.style().ensureInjected();
    }


    public DescriptionCell() {
        super(new DescriptionCellEditor());
    }

    @Override
    protected void render(Context context, String value, String viewData, SafeHtmlBuilder sb) {
        if (viewData != null) {
            if (isMultilineStyle()) {
                sb.append(TEMPLATE.html(getCellStyleName(), SafeHtmlUtils.fromSafeConstant(viewData)));
            } else {
                sb.append(TEMPLATE.text(getCellStyleName(), Utils.getTextFromHtml(viewData)));
            }
        } else if (value != null) {
            if (isMultilineStyle()) {
                sb.append(TEMPLATE.html(getCellStyleName(), SafeHtmlUtils.fromSafeConstant(value)));
            } else {
                sb.append(TEMPLATE.text(getCellStyleName(), Utils.getTextFromHtml(value)));
            }
        }
    }

    private String getCellStyleName() {
        String style;
        if (isMultilineStyle()) {
            style = RESOURCES.style().bDescriptionCell__html();
        } else {
            style = RESOURCES.style().bDescriptionCell__text();
        }
        return style;
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, String value,
                               NativeEvent event, ValueUpdater<String> valueUpdater) {
        String type = event.getType();
        if (BrowserEvents.KEYPRESS.equals(type)) {
            int charCode = event.getCharCode();
            String newValue = getStringFromCharCode(charCode);
            if (isValidChar(newValue)) {
                startEdit(context, parent, newValue, event, valueUpdater);
                return;
            }
        }
        super.onBrowserEvent(context, parent, value, event, valueUpdater);
    }

    @Override
    protected void popup(final DescriptionCellEditor popupEditor) {
        popupEditor.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
            public void setPosition(int offsetWidth, int offsetHeight) {
                popupEditor.setPopupPosition(
                        getLastParent().getParentElement().getAbsoluteLeft() - 1,
                        getLastParent().getParentElement().getAbsoluteTop() - editor.getTextAreaOffsetTop() - 1);
                Element td = getLastParent().getParentElement();
                int width = td.getClientWidth() + 2;
                if (width < MIN_TEXTAREA_WIDTH) {
                    width = MIN_TEXTAREA_WIDTH;
                }
                popupEditor.setTextAreaWidth(width);
                popupEditor.focus();
            }
        });
    }
}
